package cn.iocoder.yudao.module.game.controller.app;

import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.game.controller.admin.gameLog.vo.GameLogSaveReqVO;
import cn.iocoder.yudao.module.game.controller.admin.rechargerecord.vo.RechargeRecordSaveReqVO;
import cn.iocoder.yudao.module.game.dal.dataobject.rechargerecord.RechargeRecordDO;
import cn.iocoder.yudao.module.game.service.gameList.GameListService;
import cn.iocoder.yudao.module.game.service.gameLog.GameLogService;
import cn.iocoder.yudao.module.game.service.otherGame.JDBService;
import cn.iocoder.yudao.module.game.service.rechargerecord.RechargeRecordService;
import cn.iocoder.yudao.module.game.utils.AESDecrypt;
import cn.iocoder.yudao.module.game.utils.AESEncrypt;
import cn.iocoder.yudao.module.game.utils.SHA256WithRSAUtils;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
import cn.iocoder.yudao.module.member.service.level.MemberLevelService;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
import cn.iocoder.yudao.module.pay.service.wallet.PayWalletTransactionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.enums.UserTypeEnum.MEMBER;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static java.lang.Thread.sleep;

@Tag(name = "用户 APP - 用户收件地址")
@RestController
@RequestMapping("/game/JDB")
@Validated
public class AppJDBController {


    @Resource
    private JDBService jdbService;
    @Resource
    private GameLogService gameLogService;
    @Resource
    private PayWalletService payWalletService;
    @Resource
    private PayWalletTransactionService payWalletTransactionService;
    @Resource
    private MemberUserService memberUserService;
    @Resource
    private MemberLevelService memberlevelService;

    @PostMapping("/getGame")
    @Operation(summary = "创建用户收件地址")
    public CommonResult<Map<String, Object>> pay(@RequestBody Map<String, Object> params) throws Exception {
        return success(jdbService.login(params));
    }

    @PostMapping("/")
    @Operation(summary = "创建用户收件地址")
    public Map<String, Object> ope(@RequestParam Map<String, Object> params) throws Exception {

        Map<String, Object> bonus = new HashMap<>();
        bonus.put("5", 50);
        bonus.put("10", 50);
        bonus.put("15", 50);
        bonus.put("20", 50);
        bonus.put("25", 50);
        bonus.put("30", 50);
        bonus.put("40", 100);
        bonus.put("50", 100);
        bonus.put("60", 100);
        bonus.put("70", 100);
        bonus.put("80", 100);
        bonus.put("90", 100);
        bonus.put("100", 100);
        bonus.put("150", 500);
        bonus.put("200", 500);
        bonus.put("250", 500);
        bonus.put("300", 500);
        bonus.put("350", 500);
        bonus.put("400", 500);
        bonus.put("450", 500);
        bonus.put("500", 500);
        bonus.put("600", 1000);
        bonus.put("700", 1000);
        bonus.put("800", 1000);
        bonus.put("900", 1000);
        bonus.put("1000", 1000);
        bonus.put("1500", 5000);
        bonus.put("2000", 5000);
        bonus.put("2500", 5000);
        bonus.put("3000", 5000);
        bonus.put("4000", 10000);
        bonus.put("5000", 10000);
        bonus.put("6000", 10000);
        bonus.put("7000", 10000);
        bonus.put("8000", 10000);
        bonus.put("9000", 10000);
        bonus.put("10000", 10000);

        String x = params.get("x").toString();
        String res = AESDecrypt.decrypt(x, "c9bc03d6268f1379", "96b70e3b0285e619");
        JSONObject jsonObject = JSONObject.fromObject(res);

        createLog(Long.valueOf(jsonObject.get("uid").toString()), jsonObject);
        PayWalletDO payWalletDO = payWalletService.getOrCreateWallet(Long.valueOf(jsonObject.get("uid").toString()), MEMBER.getValue());

        MemberUserDO memberUserDO;

        MemberUserDO fReferrerUser;

        List<PayWalletTransactionDO> payWalletTransactionDOS;

        String sumP;

        switch(jsonObject.get("action").toString()) {
            case "6":
                // Get Balance (6)
                return setResponse(Long.valueOf(jsonObject.get("uid").toString()));

            case "8":
                // BetNSettle (8)
                payWalletService.reduceWalletBalance(payWalletDO.getId(),
                        jsonObject.get("transferId").toString(),
                        PayWalletBizTypeEnum.BET,
                        (long)(Double.parseDouble(jsonObject.get("bet").toString()) * 100000));
                payWalletService.addWalletBalance(payWalletDO.getId(),
                        jsonObject.get("transferId").toString(),
                        PayWalletBizTypeEnum.WIN,
                        (long)(Double.parseDouble(jsonObject.get("win").toString()) * 100000));

                memberUserDO = memberUserService.getUser(Long.valueOf(jsonObject.get("uid").toString()));

                memberlevelService.addExperience(memberUserDO.getId(),
                            (long)(Double.parseDouble(jsonObject.get("bet").toString())),
                            MemberExperienceBizTypeEnum.ORDER_GIVE,
                            jsonObject.get("transferId").toString());

                payWalletTransactionDOS =  payWalletTransactionService.list(memberUserDO.getCode(), PayWalletBizTypeEnum.RECHARGE.getType());
                sumP =  payWalletTransactionService.betSum(memberUserDO.getCode(), PayWalletBizTypeEnum.BET.getType(), 0).get("sum_p").toString();

                fReferrerUser = memberUserService.getUserByReferrer(memberUserDO.getReferrer());
                if (fReferrerUser != null) {
                    if (payWalletTransactionDOS.size() > 0 && (payWalletTransactionDOS.get(0).getPrice() / 100000) >= 20 && Long.valueOf(sumP) >= 50 && memberUserDO.getReferrerStatus().equals(0)) {
                        if (bonus.get(String.valueOf(fReferrerUser.getQualifiedNum() + 1)) != null) {
                            payWalletService.addWalletBalance(payWalletDO.getId(),
                                    jsonObject.get("transferId").toString(),
                                    PayWalletBizTypeEnum.GENERALIZATION_COMMISSION,
                                    (long)(Double.parseDouble(bonus.get(String.valueOf(fReferrerUser.getQualifiedNum() + 1)).toString()) * 100000));
                        }

                        MemberUserUpdateReqVO memberUserUpdateReqVO = new MemberUserUpdateReqVO();
                        memberUserUpdateReqVO.setReferrerStatus(1);
                        memberUserUpdateReqVO.setQualifiedNum(fReferrerUser.getQualifiedNum() + 1);
                        memberUserUpdateReqVO.setId(fReferrerUser.getId());
                        memberUserService.updateUser(memberUserUpdateReqVO);
                    }

                    PayWalletDO fReferrerPayWalletDO = payWalletService.getOrCreateWallet(fReferrerUser.getId(), UserTypeEnum.MEMBER.getValue());
                    payWalletService.addWalletBalance(fReferrerPayWalletDO.getId(),
                            jsonObject.get("transferId").toString(),
                            PayWalletBizTypeEnum.BET_COMMISSION,
                            (long)(Double.parseDouble(jsonObject.get("bet").toString()) * 100000 * 0.03 / 100));

                    MemberUserDO sReferrerUser = memberUserService.getUserByReferrer(fReferrerUser.getReferrer());
                    if (sReferrerUser != null) {
                        PayWalletDO sReferrerPayWalletDO = payWalletService.getOrCreateWallet(sReferrerUser.getId(), UserTypeEnum.MEMBER.getValue());
                        payWalletService.addWalletBalance(sReferrerPayWalletDO.getId(),
                                jsonObject.get("transferId").toString(),
                                PayWalletBizTypeEnum.BET_COMMISSION,
                                (long)(Double.parseDouble(jsonObject.get("bet").toString()) * 100000 * 0.01 / 100));

                    }
                }

                return setResponse(Long.valueOf(jsonObject.get("uid").toString()));

            case "4":
                // Cancel BetNSettle (4)
                return setResponse(Long.valueOf(jsonObject.get("uid").toString()));

            case "9":
                // Bet (9)
                payWalletService.reduceWalletBalance(payWalletDO.getId(),
                        jsonObject.get("transferId").toString(),
                        PayWalletBizTypeEnum.BET,
                        (long)(Double.parseDouble(jsonObject.get("amount").toString()) * 100000));

                memberUserDO = memberUserService.getUser(Long.valueOf(jsonObject.get("uid").toString()));

                memberlevelService.addExperience(memberUserDO.getId(),
                        (long)(Double.parseDouble(jsonObject.get("amount").toString())),
                        MemberExperienceBizTypeEnum.ORDER_GIVE,
                        jsonObject.get("transferId").toString());

                payWalletTransactionDOS =  payWalletTransactionService.list(memberUserDO.getCode(), PayWalletBizTypeEnum.RECHARGE.getType());
                sumP =  payWalletTransactionService.betSum(memberUserDO.getCode(), PayWalletBizTypeEnum.BET.getType(), 0).get("sum_p").toString();

                fReferrerUser = memberUserService.getUserByReferrer(memberUserDO.getReferrer());
                if (fReferrerUser != null) {
                    if (payWalletTransactionDOS.size() > 0 && (payWalletTransactionDOS.get(0).getPrice() / 100000) >= 20 && Long.valueOf(sumP) >= 50 && memberUserDO.getReferrerStatus().equals(0)) {
                        if (bonus.get(String.valueOf(fReferrerUser.getQualifiedNum() + 1)) != null) {
                            payWalletService.addWalletBalance(payWalletDO.getId(),
                                    jsonObject.get("transferId").toString(),
                                    PayWalletBizTypeEnum.GENERALIZATION_COMMISSION,
                                    (long)(Double.parseDouble(bonus.get(String.valueOf(fReferrerUser.getQualifiedNum() + 1)).toString()) * 100000));
                        }

                        MemberUserUpdateReqVO memberUserUpdateReqVO = new MemberUserUpdateReqVO();
                        memberUserUpdateReqVO.setReferrerStatus(1);
                        memberUserUpdateReqVO.setQualifiedNum(fReferrerUser.getQualifiedNum() + 1);
                        memberUserUpdateReqVO.setId(fReferrerUser.getId());
                        memberUserService.updateUser(memberUserUpdateReqVO);
                    }

                    PayWalletDO fReferrerPayWalletDO = payWalletService.getOrCreateWallet(fReferrerUser.getId(), UserTypeEnum.MEMBER.getValue());
                    payWalletService.addWalletBalance(fReferrerPayWalletDO.getId(),
                            jsonObject.get("transferId").toString(),
                            PayWalletBizTypeEnum.BET_COMMISSION,
                            (long)(Double.parseDouble(jsonObject.get("bet").toString()) * 100000 * 0.03 / 100));

                    MemberUserDO sReferrerUser = memberUserService.getUserByReferrer(fReferrerUser.getReferrer());
                    if (sReferrerUser != null) {
                        PayWalletDO sReferrerPayWalletDO = payWalletService.getOrCreateWallet(sReferrerUser.getId(), UserTypeEnum.MEMBER.getValue());
                        payWalletService.addWalletBalance(sReferrerPayWalletDO.getId(),
                                jsonObject.get("transferId").toString(),
                                PayWalletBizTypeEnum.BET_COMMISSION,
                                (long)(Double.parseDouble(jsonObject.get("bet").toString()) * 100000 * 0.01 / 100));

                    }
                }

                return setResponse(Long.valueOf(jsonObject.get("uid").toString()));

            case "10":
                // Settle (10)
                payWalletService.addWalletBalance(payWalletDO.getId(),
                        jsonObject.get("transferId").toString(),
                        PayWalletBizTypeEnum.WIN,
                        (long)(Double.parseDouble(jsonObject.get("amount").toString()) * 100000));
                return setResponse(Long.valueOf(jsonObject.get("uid").toString()));

            case "11":
                // Cancel Bet (11)
                payWalletService.addWalletBalance(payWalletDO.getId(),
                        jsonObject.get("transferId").toString(),
                        PayWalletBizTypeEnum.WIN,
                        (long)(Double.parseDouble(jsonObject.get("amount").toString()) * 100000));
                return setResponse(Long.valueOf(jsonObject.get("uid").toString()));

            case "12":
                // Activity Reward (12)
                payWalletService.addWalletBalance(payWalletDO.getId(),
                        jsonObject.get("transferId").toString(),
                        PayWalletBizTypeEnum.WIN,
                        (long)(Double.parseDouble(jsonObject.get("amount").toString()) * 100000));
                return setResponse(Long.valueOf(jsonObject.get("uid").toString()));

        }

        return null;
    }

    private void createLog(Long memberId, Map<String, Object> params) {

        String result = params.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining(", "));

        GameLogSaveReqVO createReqVO = new GameLogSaveReqVO();
        createReqVO.setMemberId(memberId);
        createReqVO.setRemark(result);

        if(params.get("action") == null) {
            gameLogService.createLog(createReqVO);
            return;
        }
        if(params.get("mType") != null) {
            createReqVO.setGameId(Long.valueOf(params.get("mType").toString()));
        }
        if(params.get("action").toString().equals("9")) {
            createReqVO.setOpeCoin(new BigDecimal(params.get("amount").toString()));
        }
        if(params.get("action").toString().equals("12")) {
            createReqVO.setOpeCoin(new BigDecimal(params.get("amount").toString()));
        }
        if(params.get("action").toString().equals("10")) {
            createReqVO.setPreChangeCoin(new BigDecimal(params.get("amount").toString()));
        }
        if(params.get("action").toString().equals("11")) {
            createReqVO.setPreChangeCoin(new BigDecimal(params.get("amount").toString()));
        }
        gameLogService.createLog(createReqVO);
    }

    private Map<String, Object> setResponse(Long userId) {
        Map<String, Object> res = new HashMap<>();
        res.put("status", "0000");
        res.put("err_text", "");
        PayWalletDO payWalletDO = payWalletService.getOrCreateWallet(userId, MEMBER.getValue());
        res.put("balance", new BigDecimal(payWalletDO.getBalance()).divide(new BigDecimal(100000), 2, RoundingMode.HALF_UP));
        return res;
    }

}
